# encoding: utf-8
import json, codecs, time, os, requests, copy
from pprint import pprint
import threading
import threading
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm


print('开始时间 : ', time.ctime())
start_time = time.time()
NUM_THREADS = 10
file_lock = threading.Lock()

# TODO !!!!该模型为付费模型，请不要大量请求
HOST = "http://10.60.244.181:8776"

'''
远程调用 VGC NLP 服务的代码
'''
headers = {
    "accept": "application/json",
    "Content-Type": "application/json",
}

## 工具类请求模式
class Tool:
    def __init__(self):
        self.headers = headers
        self.HOST = HOST

    def clean_sentence(self, customer_voice):
        '''
        简单的数据预处理，清除掉不相干的文字，避免影响模型分析
        customer_voice : 原始的用户语句，使用之前清除掉类似LSEP等windows的空格
        '''
        url = self.HOST + "/clean_sentence"
        data = {
            "customer_voice": customer_voice
        }
        response = requests.post(
            url,
            headers=self.headers,
            json=data
        )
        response = response.json()
        result = response['message']['result']
        return result


    def sentiment_analysis(
            self,
            customer_voice,
            content,
            vehicle
    ):
        '''
        使用 {customer_voice} 站在 {vehicle} 的角度 对 {content} 进行分析
        确保customer_voice 和 content 必须存在
        当vehicle不存在customer_voice中时候，使用 '' 空字符串代替
        返回分为
        [
            正向情感-5
            正向情感-4
            中性情感-3
            负向情感-2
            负向情感-1
        ]
        '''
        url = self.HOST + "/sentiment_analysis"
        data = {
            "customer_voice": customer_voice,
            'content': content,
            'vehicle': vehicle
        }
        response = requests.post(
            url,
            headers=self.headers,
            json=data
        )
        response = response.json()
        result = response['message']['result']
        return result

    def ner_analysis(
            self,
            customer_voice,
            content
    ):
        '''
        提取 {customer_voice} 中和 {content} 相关的语句
        确保customer_voice 和 content 必须存在
        '''
        url = self.HOST + "/ner_analysis"
        data = {
            "customer_voice": customer_voice,
            'content': content
        }
        response = requests.post(
            url,
            headers=self.headers,
            json=data
        )
        response = response.json()
        result = response['message']['result']
        return result



    def sentence_split(
            self,
            customer_voice,
            vehicle
    ):
        '''
        提取 {customer_voice} 中和 {vehicle} 相关的语句
        确保customer_voice 和 vehicle 必须存在
        '''
        url = self.HOST + "/sentence_split"
        data = {
            "customer_voice": customer_voice,
            'vehicle': vehicle
        }
        response = requests.post(
            url,
            headers=self.headers,
            json=data
        )
        response = response.json()
        result = response['message']['result']
        return result

tool = Tool()
#
# if __name__ == '__main__':
#     tool = Tool()
    # 1. 测试 sentiment_analysis
    # sentence = "外观方面还是很大众，特别是前脸辨识度很高 价格方面优惠2万，感觉力度还有进一步加强，这样就更有性价比了。 车外观看起来不大，但是内部空间使用上还是没什么大问题，后备箱也还行吧，肯定比不了三厢车，但是主打一个够用还是没问题的。 没有试驾，因为当时试驾车别的顾客开出去了，而且当时时间也晚了就没有试驾 同样没有试驾，所以续航上没有发言权 外观上刚也说了很大众，符合大家对大众的一贯的认知，虽不惊艳，但是看着也很精致。 内饰主打的简单很简约，也符合大众的传统，没有很多花里胡哨的东西，低调内敛就很好了 价格方面，我还是感觉差了一点意思，这个车顶上的宣传标语说优惠4.4，是不是包含了报废补贴、置换补贴和贷款返息补贴等等就不得而知了。 智能化方面，我个人觉得离我看的这款车和这个配置还是有一定距离，因为毕竟是居家的车型，主要一个经济实用，所以这方面的配置少了一些也是可以理解的。"
    # content = '外观'
    # vehicle = ''
    # result = tool.sentiment_analysis(
    #     customer_voice=sentence,
    #     content=content,
    #     vehicle=vehicle
    # )
    # print(result)
    # print(type(result))

    # 2. 测试 ner_analysis
    # sentence = "外观方面还是很大众，特别是前脸辨识度很高 价格方面优惠2万，感觉力度还有进一步加强，这样就更有性价比了。 车外观看起来不大，但是内部空间使用上还是没什么大问题，后备箱也还行吧，肯定比不了三厢车，但是主打一个够用还是没问题的。 没有试驾，因为当时试驾车别的顾客开出去了，而且当时时间也晚了就没有试驾 同样没有试驾，所以续航上没有发言权 外观上刚也说了很大众，符合大家对大众的一贯的认知，虽不惊艳，但是看着也很精致。 内饰主打的简单很简约，也符合大众的传统，没有很多花里胡哨的东西，低调内敛就很好了 价格方面，我还是感觉差了一点意思，这个车顶上的宣传标语说优惠4.4，是不是包含了报废补贴、置换补贴和贷款返息补贴等等就不得而知了。 智能化方面，我个人觉得离我看的这款车和这个配置还是有一定距离，因为毕竟是居家的车型，主要一个经济实用，所以这方面的配置少了一些也是可以理解的。"
    # content = '外观'
    # result = tool.ner_analysis(
    #     customer_voice=sentence,
    #     content=content
    # )
    # print(result)
    # print(type(result))

    # # 3. 测试 sentence_split
    # sentence = "外观方面还是很大众，特别是前脸辨识度很高 价格方面优惠2万，感觉力度还有进一步加强，这样就更有性价比了。 车外观看起来不大，但是内部空间使用上还是没什么大问题，后备箱也还行吧，肯定比不了三厢车，但是主打一个够用还是没问题的。 没有试驾，因为当时试驾车别的顾客开出去了，而且当时时间也晚了就没有试驾 同样没有试驾，所以续航上没有发言权 外观上刚也说了很大众，符合大家对大众的一贯的认知，虽不惊艳，但是看着也很精致。 内饰主打的简单很简约，也符合大众的传统，没有很多花里胡哨的东西，低调内敛就很好了 价格方面，我还是感觉差了一点意思，这个车顶上的宣传标语说优惠4.4，是不是包含了报废补贴、置换补贴和贷款返息补贴等等就不得而知了。 智能化方面，我个人觉得离我看的这款车和这个配置还是有一定距离，因为毕竟是居家的车型，主要一个经济实用，所以这方面的配置少了一些也是可以理解的。"
    # vehicle = '大众'
    # result = tool.sentence_split(
    #     customer_voice=sentence,
    #     vehicle=vehicle
    # )
    # print(result)
    # print(type(result))
    # print('当前去除了多少个字符' , len(sentence) - len(result))
    #


class SimpleNLP:
    def __init__(self):
        self.headers = headers
        self.HOST = HOST

    def clarify_vehicle_relevant_analysis(
            self,
            customer_voice
    ):
        '''
        根据customer_voice来识别是否与车辆相关
        [
            客户反馈和车辆相关
            客户反馈和车辆不相关
            客户反馈中无法判断是否和车辆相关
        ]
        '''
        url = self.HOST + "/clarify_vehicle_relevant_analysis"
        data = {
            "customer_voice": customer_voice,
        }
        response = requests.post(
            url,
            headers=self.headers,
            json=data
        )
        response = response.json()
        result = response['message']['result']
        return result


    def clarify_forum_analysis(
            self,
            customer_voice
    ):
        '''
        根据customer_voice来识别是否与车辆相关
        [
            客户反馈和车辆相关
            客户反馈和车辆不相关
            客户反馈中无法判断是否和车辆相关
        ]
        '''
        url = self.HOST + "/clarify_forum_analysis"
        data = {
            "customer_voice": customer_voice,
        }
        response = requests.post(
            url,
            headers=self.headers,
            json=data
        )
        response = response.json()
        result = response['message']['result']
        return result

    def purchase_clarify_analysis(
            self,
            customer_voice
    ):
        '''
        根据customer_voice来识别是否与车辆相关
        [
            客户反馈和车辆相关
            客户反馈和车辆不相关
            客户反馈中无法判断是否和车辆相关
        ]
        '''
        url = self.HOST + "/purchase_clarify_analysis"
        data = {
            "customer_voice": customer_voice,
        }
        response = requests.post(
            url,
            headers=self.headers,
            json=data
        )
        response = response.json()
        result = response['message']['result']
        return result


simplenlp = SimpleNLP()

# if __name__ == '__main__':
#     customer_voice = "外观方面还是很大众，特别是前脸辨识度很高 价格方面优惠2万，感觉力度还有进一步加强，这样就更有性价比了。 车外观看起来不大，但是内部空间使用上还是没什么大问题，后备箱也还行吧，肯定比不了三厢车，但是主打一个够用还是没问题的。 没有试驾，因为当时试驾车别的顾客开出去了，而且当时时间也晚了就没有试驾 同样没有试驾，所以续航上没有发言权 外观上刚也说了很大众，符合大家对大众的一贯的认知，虽不惊艳，但是看着也很精致。 内饰主打的简单很简约，也符合大众的传统，没有很多花里胡哨的东西，低调内敛就很好了 价格方面，我还是感觉差了一点意思，这个车顶上的宣传标语说优惠4.4，是不是包含了报废补贴、置换补贴和贷款返息补贴等等就不得而知了。 智能化方面，我个人觉得离我看的这款车和这个配置还是有一定距离，因为毕竟是居家的车型，主要一个经济实用，所以这方面的配置少了一些也是可以理解的。"
#     result = simplenlp.purchase_clarify_analysis(
#         customer_voice=customer_voice
#     )
#     print(result)
#     print(type(result))



class CUZU:
    def __init__(self):
        self.headers = headers
        self.HOST = HOST

    def feel_analysis_withvehicle(
            self,
            customer_voice,
            vehicle
    ):
        '''
        使用customer_voice来分析针对于vehicle的客户感受
        '''
        url = self.HOST + "/feel_analysis_withvehicle"
        data = {
            "customer_voice": customer_voice,
            "vehicle": vehicle,
        }
        response = requests.post(
            url,
            headers=self.headers,
            json=data
        )
        response = response.json()
        result = response['message']['result']
        return result


    def feel_analysis_withoutvehicle(
            self,
            customer_voice
    ):
        '''
        使用customer_voice来分析针对于vehicle的客户感受
        '''
        url = self.HOST + "/feel_analysis_withoutvehicle"
        data = {
            "customer_voice": customer_voice
        }
        response = requests.post(
            url,
            headers=self.headers,
            json=data
        )
        response = response.json()
        result = response['message']['result']
        return result


cuzu = CUZU()


# if __name__ == '__main__':
#     customer_voice = "id3换成磷酸铁锂后，成本更有优势，效果明显大众ID.3作为MEB平台的首款战略车型，其电池技术路线的调整不仅是产品升级，更是一场关乎企业未来竞争力的系统性变革。...二、三元锂与磷酸铁锂的技术博弈 早期ID.3采用的三元锂电池（NCM）以高能量密度著称，但随着市场竞争加剧，其固有缺陷逐渐暴露：钴资源的稀缺性推高成本，热稳定性差导致的安全隐患，以及低温环境下的性能衰减。...三、成本控制与供应链安全的双重考量 1. 经济性重构：磷酸铁锂材料成本较三元锂低40%以上，叠加规模化生产带来的边际成本下降，ID.3入门车型价格有望下探至15万元区间，直接对标比亚迪海豚、广汽AION Y等竞品。...四、技术升级带来的体验革命 1. 续航与充电效率：通过电池管理系统（BMS）算法优化，新ID.3在CLTC工况下续航提升至450km（较三元锂版本增加50km），快充功率突破100kW，30%-80%充电时间缩短至25分钟。...数据显示，ID.3在2024年推出磷酸铁锂版本后，订单量环比增长270%，印证了市场对高性价比产品的强烈需求。"
#     # vehicle = "ID.3"
#     result = cuzu.feel_analysis_withoutvehicle(
#         customer_voice=customer_voice
#         # vehicle=vehicle
#     )
#     print(result)
#     print(type(result))

def split_model(model_name):
    if ',' in model_name :
        model = model_name.split(',')[0]
    else:
        model = model_name
    return model

def remove_hashtag(customer_voice, length=10):
    temp_customer_voice = copy.deepcopy(customer_voice)
    temp_customer_voice = temp_customer_voice.\
        replace('#', '').\
        replace(' ', '').\
        replace('\n', '').\
        replace('\r', '').\
        replace('\t', '').\
        replace('"', '').\
        replace("'", "").\
        replace('  ', "").\
        replace('“', '').\
        replace('”', '').\
        replace('{', '').\
        replace('}', '').\
        replace('，', '').\
        replace('。', '').\
        replace('？', '').\
        replace('！', '').\
        replace('；', '').\
        replace('：', '').\
        replace('（', '').\
        replace('）', '').\
        replace('【', '').\
        replace('】', '').\
        replace('《', '').\
        replace('》', '').\
        replace('‘', '').\
        replace('’', '').\
        replace('“', '').\
        replace('”', '').\
        replace('‘', '').\
        replace('’', '').\
        replace('…', '').\
        replace('—', '')
    if len(temp_customer_voice) > length:
        return customer_voice
    else:
        return ''


def preprocess(data):
    customer_voice = data[0]
    model = split_model(data[1])

    # 当去除标点符号的所有字符串长度小于10时候，直接丢弃
    customer_voice = remove_hashtag(
        customer_voice=customer_voice
    )
    if len(customer_voice)==0:
        return {
            'customer_voice': customer_voice,
            'status_code': 0, # 当前数据中文字符太少，无需进行分析
            'msg' : '当前文本包含中文字符数量小于10'
        }

    # 0. 首先数据去除无关符号
    clean_customer_voice = tool.clean_sentence(
        customer_voice=customer_voice
    )

    # 1. 首先判断是否和车辆相关
    vehicle_relevant_res = simplenlp.clarify_vehicle_relevant_analysis(
        customer_voice=clean_customer_voice
    )
    if (vehicle_relevant_res == '客户反馈和车辆不相关') or (vehicle_relevant_res == '客户反馈中无法判断是否和车辆相关'):
        return {
            'customer_voice': customer_voice,
            'clean_customer_voice' : clean_customer_voice,
            'vehicle_relevant_res' : vehicle_relevant_res,
            'status_code' : 1, # 当前文本和车辆内容不是强相关内容
            'msg': '当前文本和车辆内容不是强相关内容'
        }
    else:
        # 2. 判断customer voice的类别主题
        forum_types_res = simplenlp.clarify_forum_analysis(
            customer_voice=clean_customer_voice
        )

        # 3. 如果是车辆营销内容 ，直接跳过
        if '车辆营销内容' in forum_types_res:
            return {
                'customer_voice': customer_voice,
                'clean_customer_voice' : clean_customer_voice,
                'vehicle_relevant_res' : vehicle_relevant_res,
                'forum_types_res' : forum_types_res,
                'status_code' : 2, # 当前文本偏向于车辆营销内容
                'msg' : '当前文本偏向于车辆营销内容'
            }
        if ('车辆评价体验' in forum_types_res) or \
                ('不同车型间对比' in forum_types_res) or \
                ('车辆质量与可靠性' in forum_types_res) :
            # 3. 判断用户的购买欲望
            purchase_desire_res = simplenlp.purchase_clarify_analysis(
                customer_voice=clean_customer_voice
            )

            # 5. 接下来进行cuzu 分析
            if '不同车型间对比' in forum_types_res:
                # 4. 去除和车型不相关的干扰噪音数据
                target_vehicle_sentence = tool.sentence_split(
                    customer_voice=clean_customer_voice,
                    vehicle=model
                )
                if isinstance(target_vehicle_sentence, list):
                    target_vehicle_sentence = ' '.join(target_vehicle_sentence)
                else:
                    ...
                cuzu_res = cuzu.feel_analysis_withvehicle(
                    customer_voice=target_vehicle_sentence,
                    vehicle=model
                )
                return {
                    'customer_voice': customer_voice,
                    'clean_customer_voice' : clean_customer_voice,
                    'target_vehicle_sentence': target_vehicle_sentence,
                    'vehicle_relevant_res' : vehicle_relevant_res,
                    'forum_types_res' : forum_types_res,
                    'purchase_desire_res' : purchase_desire_res,
                    'cuzu_res' : cuzu_res,
                    'status_code' : 3, # 当前文本偏向于车辆评价体验
                    'msg' : '当前文本偏向于车辆评价体验，且为不同车型的对比内容'
                }
            else:
                cuzu_res = cuzu.feel_analysis_withoutvehicle(
                    customer_voice=clean_customer_voice
                )
                return {
                    'customer_voice': customer_voice,
                    'clean_customer_voice' : clean_customer_voice,
                    'vehicle_relevant_res' : vehicle_relevant_res,
                    'forum_types_res' : forum_types_res,
                    'purchase_desire_res' : purchase_desire_res,
                    'cuzu_res' : cuzu_res,
                    'status_code' : 4, # 当前文本偏向于车辆评价体验
                    'msg' : '当前文本偏向于车辆评价体验'
                }
        else:
            ...
    return response



def write_result(result):
    """线程安全写入函数"""
    with file_lock:  # 自动获取/释放锁
        with codecs.open(filename='01-analysis.json',
                         mode='a', encoding='utf-8') as fa:
            fa.write(json.dumps(result, ensure_ascii=False))
            fa.write('\r\n')
            fa.flush()



def main():
    # 创建线程池 (推荐使用 with 自动管理)
    with codecs.open(filename='测试数据.json', mode='r', encoding='utf-8') as fr:
        data_list = json.load(fr)

    with ThreadPoolExecutor(max_workers=NUM_THREADS) as executor:
        # 提交所有任务
        futures = [
            executor.submit(
                lambda e: write_result(preprocess(e)),  # 组合处理与写入
                element
            ) for element in data_list
        ]

        # 等待所有任务完成（可选进度监控）
        for future in futures:
            future.result()



if __name__ == '__main__':
    main()


